package com.ruoyi.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.entity.ChartQueryDTO;
import com.ruoyi.entity.Dataset;
import com.ruoyi.entity.ExcelData;
import com.ruoyi.entity.QuickChart;
import com.ruoyi.service.QuickChartService;
import com.ruoyi.service.RagFlowService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.TimeUnit;
import okhttp3.*;

@Slf4j
@Service
public class QuickChartServiceImpl implements QuickChartService {

    @Value("${ollama.url}")
    private String ollamaUrl;

    @Autowired
    private QuickChartService quickChartService;

    @Autowired
    private RagFlowService ragFlowService;

    @Override
    public QuickChart generateSmartChart(ChartQueryDTO query) {
        try {
            // 1. 获取RAG数据
            ExcelData excelData = ragFlowService.fetchExcelData(query);

            // 2. 构造智能提示
            String prompt = buildSmartPrompt(query.getQuery(), excelData);

            // 3. 调用Ollama API
            String aiResponse = callOllama(prompt);

            // 4. 数据清洗转换
            return convertToChartConfig(aiResponse);
        }catch (IOException e){
            throw new RuntimeException("Ollama API调用失败", e);
        }

    }

    private String buildSmartPrompt(String userQuery, ExcelData data) {
        return String.format(
                "[系统指令]\n" +
                        "你是一个数据分析助手，请根据以下要求和数据生成图表配置：\n" +
                        "用户需求：%s\n" +
                        "数据样本：%s\n\n" +
                        "输出要求：\n" +
                        "- 使用JSON格式\n" +
                        "- 包含chart_type/labels/datasets字段\n" +
                        "- 图表类型自动选择最合适的\n" +
                        "- 颜色使用十六进制代码\n\n" +
                        "示例格式：\n" +
                        "{\n" +
                        "  \"chart_type\": \"bar\",\n" +
                        "  \"labels\": [\"Q1\",\"Q2\"],\n" +
                        "  \"datasets\": [{\n" +
                        "    \"label\": \"销售额\",\n" +
                        "    \"data\": [1200, 1800],\n" +
                        "    \"backgroundColor\": \"#4CAF50\"\n" +
                        "  }]\n" +
                        "}",
                userQuery,
                data.toString()
        );
    }

    private String callOllama(String prompt) throws IOException{
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();

        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        String escapedPrompt = prompt
                .replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\n", "\\n");

        String jsonBody = String.format("{\"model\": \"deepseek:14b\", \"prompt\": \"%s\"}", escapedPrompt);
        RequestBody body = RequestBody.create(jsonBody, mediaType);

        Request request = new Request.Builder()
                .url(ollamaUrl + "/api/generate")
                .post(body)
                .addHeader("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Ollama API请求失败: " + response.code() + " - " + response.message());
            }
            return response.body().string();
        }
    }

    private QuickChart convertToChartConfig(String rawResponse) {
        String jsonStr = rawResponse
                .replaceAll("(?s)^.*?(\\{.*\\}).*$", "$1")
                .replaceAll("[^\\x20-\\x7e]", "")
                .replaceAll("(\\w+)\\s*?:", "\"$1\":")
                .replaceAll("'", "\"");

        try {
            JSONObject json = JSON.parseObject(jsonStr);
            QuickChart config = new QuickChart();
            config.setChartType(json.getString("chart_type"));

            // 处理labels
            JSONArray labels = json.getJSONArray("labels");
            config.setLabels(labels.toList(String.class));

            // 处理datasets
            JSONArray datasets = json.getJSONArray("datasets");
            List<Dataset> datasetList = datasets.stream().map(d -> {
                JSONObject obj = (JSONObject) d;
                Dataset ds = new Dataset();
                ds.setLabel(obj.getString("label"));

                JSONArray dataArray = obj.getJSONArray("data");
                List<Double> dataList = dataArray.stream()
                        .map(value -> {
                            if (value instanceof Integer) {
                                return ((Integer) value).doubleValue();
                            } else if (value instanceof Long) {
                                return ((Long) value).doubleValue();
                            } else if (value instanceof String) {
                                return Double.parseDouble((String) value);
                            } else if (value instanceof Number) {
                                return ((Number) value).doubleValue();
                            } else {
                                throw new IllegalArgumentException("Unsupported data type: " + value.getClass());
                            }
                        })
                        .collect(Collectors.toList());
                ds.setData(dataList);

                ds.setBackgroundColor(obj.getString("backgroundColor"));

                log.debug("原始响应：{}", rawResponse);
                log.debug("清洗后JSON：{}", jsonStr);

                return ds;
            }).collect(Collectors.toList());

            config.setDatasets(datasetList);
            return config;
        } catch (Exception e) {
            throw new RuntimeException("JSON解析失败: " + e.getMessage(), e);
        }
    }
}
